home *** CD-ROM | disk | FTP | other *** search
/ CD Schooolhouse Version 10.0 / CD Schooolhouse Version 10.0.ISO / pc / dos / misc / mvsp13 / reformat.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1994-03-03  |  15.9 KB  |  551 lines

  1. PROGRAM reformat;
  2. {$R+}
  3. {
  4.                             REFORMAT
  5.         (C) Copyright - Warren L. Kovach      - Feb., 1986
  6.                         Department of Biology
  7.                         Indiana University
  8.                         Bloomington, IN  47405
  9.  
  10.   Converts data matrix from normal form, with species as rows and
  11.   samples as columns, to condensed format used by Hill's DECORANA
  12.   program.  This condensed format consists of data ponts entered
  13.   as couplets consisting of the number for the species and the
  14.   abundance.  Each line of the file begins with the number of the
  15.   sample, followed by the couplets.  The data for a sample may
  16.   continue onto other lines.
  17.  
  18.   See the user's manuals for MVSP and DECORANA for details on the
  19.   structure of the data files.
  20.  
  21.   MVSP is a multivariate statistical package available from the
  22.   author of this utility.
  23.  
  24.   DECORANA is a detrended correspondance analysis program,
  25.   written by M.O. Hill and distributed for mainframe computers by
  26.   Hugh G. Gauch (Ecology and Systematics, Cornell University,
  27.   Ithica, NY  14850).  This program was modified for the IBM PC
  28.   by Christopher Clampitt (Department of Botany, University of
  29.   Washington, Seattle, WA 98195).
  30.  
  31.   This program program may be freely copied and distributed, as
  32.   long as no price is charged for it, other than the price of the
  33.   media (not to exceed $5).  Any bugs or suggestions should be
  34.   reported to me at the address given above.
  35.  
  36.   - Warren L. Kovach
  37. }
  38. {$I-}  { turn off Turbo I/O error checking, use IOCHECK instead }
  39.  
  40. CONST
  41.   maxdim = 95;
  42.   bell   = #07;
  43.   cr     = #13;
  44.   space  = #32;
  45.   ioval  : integer = 0;
  46.   ioerr  : boolean = false;
  47. TYPE
  48.   two_d_array_type = array[1..maxdim,1..maxdim] of real;
  49.   name_lab         = string[8];
  50.   name_array       = array[1..maxdim] of name_lab;
  51.   long_string      = string[70];
  52. VAR
  53.   data            : two_d_array_type;
  54.   col_lab,row_lab : name_array;
  55.   in_label        : name_lab;
  56.   title,
  57.   infilename,
  58.   outfilename     : long_string;
  59.   i,j,
  60.   columns,rows    : integer;
  61.   labels_present  : boolean;
  62.   datin           : real;
  63.   infile,outfile  : text [$800];  { use 2K buffer }
  64.   marker,labels   : char;
  65.  
  66. { ****************************************************************** }
  67.  
  68. PROCEDURE syntax;
  69. BEGIN
  70.   writeln(bell);
  71.   writeln('Filenames must be specified on the DOS command line.');
  72.   writeln;
  73.   writeln('Command syntax is "REFORMAT infilename [outfilename]".');
  74.   writeln('  If "outfilename" is omitted, outfile defaults to "infilename.RFM"');
  75. END;
  76.  
  77. { ****************************************************************** }
  78.  
  79. PROCEDURE IOCheck;
  80. {    Checks for I/O errors through the TURBO procedure IOresult,
  81.      & then prints out an appropriate message before aborting.  }
  82. VAR
  83.   Ch                   : Char;
  84. BEGIN
  85.   IOVal := IOresult;
  86.   IOErr := (IOVal <> 0);
  87.   if IOErr then begin
  88.     normvideo;
  89.     Write(bell);
  90.     writeln;
  91.     case IOVal of
  92.       $01 : Write('File does not exist');
  93.       $02 : Write('File not open for input');
  94.       $03 : Write('File not open for output');
  95.       $04 : Write('File not open');
  96.       $05 : Write('Can''t read from this file');
  97.       $06 : Write('Can''t write to this file');
  98.       $08 : Write('Disk write error, disk may be full');
  99.       $09 : Write('Illegal character input; check data file');
  100.       $10 : Write('Error in numeric format; check data file');
  101.       $99 : Write('Unexpected end of file');
  102.       $F0 : Write('Disk write error, disk may be full');
  103.       $F1 : Write('Directory is full');
  104.       $F3,$243 : Write
  105.    ('Not enough file handles; put "FILES=16" in CONFIG.SYS and reboot');
  106.       $FF : Write
  107.    ('File has disappeared; make sure disk was not changed');
  108.     else      Write('Unknown I/O error:  ',IOVal:3);
  109.     end;
  110.     writeln;
  111.     writeln('Aborting..');
  112.     lowvideo;
  113.     close(infile);IOCHECK;close(outfile);IOCHECK;
  114.     HALT;
  115.   end;
  116. END; { of proc IOCheck }
  117.  
  118. { ****************************************************************** }
  119.  
  120. PROCEDURE yesno(VAR answer:boolean);
  121. { Gets character input from user and checks to make sure it is
  122.   a 'Y' or 'N' for yes or no.  }
  123. VAR
  124.   input  :char;
  125. {-------------------------------------------------------------------}
  126.   PROCEDURE rvsvideo;
  127.   BEGIN
  128.     textcolor(black);
  129.     textbackground(lightgray);
  130.   END;  { procedure rvsvideo }
  131. {-------------------------------------------------------------------}
  132. BEGIN { procedure yesno }
  133.   repeat
  134.     rvsvideo;
  135.     write('Y');
  136.     lowvideo;
  137.     gotoxy(wherex-1,wherey);
  138.     read (kbd,input);
  139.     input := upcase(input);
  140.     if not (input in ['Y','N',cr]) then write(bell);
  141.   until (input in ['Y','N',cr]);
  142.   answer := input in ['Y',cr];
  143.   if input = cr then input:='Y';
  144.   writeln(input);
  145.   writeln;
  146. END;
  147.  
  148. { ****************************************************************** }
  149.  
  150. FUNCTION uppercase(str:long_string):long_string;
  151.   { converts a string to uppercase }
  152. VAR
  153.   i       : integer;
  154.   new_str : long_string;
  155. BEGIN
  156.   new_str := '';
  157.   for i := 1 to length(str) do
  158.     new_str := new_str + upcase(str[i]);
  159.   uppercase := new_str;
  160. END;
  161.  
  162. { ****************************************************************** }
  163.  
  164. PROCEDURE openfiles;
  165. VAR
  166.   len                    : integer;
  167.   fileexist,confirm      : boolean;
  168. {-------------------------------------------------------------------}
  169. FUNCTION exist(filename:long_string):boolean;
  170. VAR
  171.   fil : file;
  172. BEGIN
  173.   assign(fil,filename);
  174.   reset(fil);
  175.   exist := (ioresult = 0);
  176.   {$i+}
  177.   close(fil);
  178.   {$I-}
  179. END;
  180. {-------------------------------------------------------------------}
  181. BEGIN { openfiles }
  182. { get filenames from command line parameters }
  183.   infilename := UPPERCASE(paramstr(1));
  184.   outfilename := UPPERCASE(paramstr(2));
  185.  
  186. { if no output filename given, create one with extension '.RFM' }
  187.   if paramstr(2) = '' then begin
  188.     len := pos('.',infilename);
  189.     if len = 0 then len := length(infilename)+1;    { len=0 if no '.' found }
  190.     outfilename := concat(copy(infilename,1,len-1),'.RFM');
  191.   end;
  192.  
  193. { check for existence of input file }
  194.   fileexist := exist(infilename);
  195.   if not fileexist then begin
  196.     writeln(bell);
  197.     normvideo;
  198.     writeln('File not found, try again');
  199.     lowvideo;
  200.     halt;
  201.   end;
  202.  
  203. { warn user if output file already exists }
  204.   fileexist := exist(outfilename);
  205.   if fileexist then begin
  206.     normvideo;
  207.     writeln(bell);
  208.     write('File "',outfilename,'" already exists; overwrite? ');
  209.     lowvideo;
  210.     YESNO(confirm);
  211.     if not confirm then halt;
  212.   end;
  213.  
  214. { open files }
  215.   assign(infile,infilename);
  216.   reset(infile);IOCHECK;
  217.   assign(outfile,outfilename);
  218.   rewrite(outfile);IOCHECK;
  219. END; { openfiles }
  220.  
  221. { ****************************************************************** }
  222.  
  223. PROCEDURE check_for_eof;
  224.   { Check for end of file while reading data }
  225. BEGIN
  226.   if eof(infile) then begin
  227.     normvideo;
  228.     writeln(bell);
  229.     write('Not enough data in file.');
  230.     close(infile);IOCHECK;
  231.     close(outfile);IOCHECK;
  232.     writeln;writeln;
  233.     write('ABORTING...');
  234.     lowvideo;
  235.     halt;
  236.   end;
  237. END;
  238.  
  239. { ****************************************************************** }
  240.  
  241. PROCEDURE parse_label (VAR lab : name_lab);
  242.   { reads labels from the input file.  Labels must be
  243.     separated by spaces or end of line }
  244. VAR
  245.   word_found : boolean;
  246.   end_word   : boolean;
  247.   ch         : char;
  248. BEGIN
  249.   lab := '';
  250.   word_found := false;
  251.   end_word := false;
  252.   repeat
  253.     read(infile,ch);IOCHECK;
  254.     CHECK_FOR_EOF;
  255.     if ch > space then begin
  256.       word_found := true;
  257.       lab := concat(lab,ch);
  258.     end;
  259.     if ((ch = space) or (ch = cr)) and word_found then
  260.       end_word := true;
  261.   until word_found and end_word;
  262. END;
  263.  
  264. { ****************************************************************** }
  265.  
  266. PROCEDURE read_mvsp;
  267.        { read data from input file }
  268. BEGIN
  269. { read header }
  270.   readln(infile,marker,labels,rows,columns,title);IOCHECK;
  271.   if upcase(labels) = 'L' then labels_present := true
  272.     else labels_present := false;
  273.  
  274. { read column labels }
  275.   if labels_present then begin
  276.     for i := 1 to columns do  begin
  277.       PARSE_LABEL(in_label);
  278.       col_lab[i] := in_label;
  279.     end;
  280.     columns := columns + 1;      { one extra column for row labels }
  281.   end;
  282.  
  283. { read data }
  284.   for i:=1 to rows do begin
  285.     for j:=1 to columns do begin
  286.       CHECK_FOR_EOF;
  287.       if (labels_present) and (j = 1) then begin  { read row labels }
  288.         PARSE_LABEL(in_label);
  289.         row_lab[i] := in_label;
  290.       end
  291.       else begin
  292.         read (infile,datin);IOCHECK;              { read data points }
  293.         if labels_present then data[i,j-1]:=datin
  294.           else data[i,j] := datin;
  295.       end;
  296.     end; { for j }
  297.     if labels_present then begin
  298.       readln(infile);IOCHECK;
  299.     end;
  300.   end; { for i }
  301.   if labels_present then columns := columns - 1;
  302.   reset(infile);  { reset so EOF is false on subsequent IOCHECK's}
  303.   IOCHECK;
  304. END;
  305.  
  306. { ****************************************************************** }
  307.  
  308. PROCEDURE read_decorana;
  309.  
  310. VAR
  311.   transform1         : real;
  312.   couplets_per_line,
  313.   species,sample     : integer;
  314.   format             : long_string;
  315.  
  316. BEGIN
  317. { initialize variables }
  318.   rows := 0;
  319.   columns := 0;
  320.   sample := -1;
  321.  
  322. { read parameters }
  323.   readln(infile,transform1);IOCHECK;
  324.   if transform1 <> -1 then begin    { skip transformation statements }
  325.     for i := 1 to 9 do begin
  326.       readln(infile);IOCHECK;
  327.     end;
  328.   end;
  329.   readln(infile);IOCHECK;        { skip operating parameters }
  330.   readln(infile,title);IOCHECK;  { read title }
  331.   readln(infile,format);IOCHECK; { read format statement }
  332.   couplets_per_line := ((ord(format[69])-48) * 10) + (ord(format[70])-48);
  333.  
  334. { read data }
  335. { Note that data points must be separated by at least one space }
  336.  
  337.   while sample <> 0 do begin
  338.     read(infile,sample);IOCHECK;
  339.     CHECK_FOR_EOF;
  340.     if sample > columns then columns := sample;
  341.     for i := 1 to couplets_per_line do begin
  342.       if not eoln(infile) then begin
  343.         read(infile,species,datin);IOCHECK;
  344.         CHECK_FOR_EOF;
  345.         data[sample,species] := datin;
  346.         if species > rows then rows := species;
  347.       end;
  348.     end;
  349.     readln(infile);IOCHECK;
  350.   end; { while }
  351.  
  352. { read labels }
  353.   for i := 1 to rows do begin
  354.     read(infile,in_label);IOCHECK;
  355.     CHECK_FOR_EOF;
  356.     row_lab[i] := in_label;
  357.     if (i mod 10 = 0) or (i = rows) then begin
  358.       readln(infile);IOCHECK;
  359.     end;
  360.   end;
  361.   for i := 1 to columns do begin
  362.     read(infile,in_label);IOCHECK;
  363.     CHECK_FOR_EOF;
  364.     col_lab[i] := in_label;
  365.     if (i mod 10 = 0) or (i = columns) then begin
  366.       readln(infile);IOCHECK;
  367.     end;
  368.   end;
  369.   reset(infile); { reset so EOF is false on subsequent IOCHECK's}
  370.   IOCHECK;
  371. END;
  372.  
  373. { ****************************************************************** }
  374.  
  375. PROCEDURE write_decorana;
  376. TYPE
  377.   const_array = array[1..10] of string[16];
  378. CONST
  379.   octave_transform : const_array = ('     .25      1.','     .75      2.',
  380.                                     '    1.50      3.','    3.00      4.',
  381.                                     '    6.00      5.','   12.00      6.',
  382.                                     '   24.00      7.','   48.00      8.',
  383.                                     '   82.00      9.','   -1.00      0.');
  384.   options = '    0    0    0    0';
  385.   format =
  386.   '(I2,1X,6(I3,F9.2))                                                  06';
  387.   no_omitted_samples1 = '    0';
  388.   no_omitted_samples2 = '   0';
  389. VAR
  390.   number_written : integer;
  391.   octave_trans   : boolean;
  392. BEGIN
  393.   writeln;write('Set up DECORANA file for octave transformation? ');
  394.   YESNO(octave_trans);
  395.   write('Processing: ',infilename,' => ',outfilename,'...');
  396.  
  397. { write out option parameters }
  398.   if octave_trans then for i := 1 to 10 do begin
  399.     writeln(outfile,octave_transform[i]);IOCHECK;
  400.   end
  401.   else begin
  402.     writeln(outfile,octave_transform[10]);IOCHECK;
  403.   end;
  404.   writeln(outfile,options);IOCHECK;
  405.   writeln(outfile,title);IOCHECK;
  406.   writeln(outfile,format);IOCHECK;
  407.  
  408. { write out data }
  409.   for j := 1 to columns do begin
  410.     number_written := 0;
  411.     for i := 1 to rows do begin
  412.       if data[i,j] <> 0 then begin          { write out non-zero data }
  413.         if number_written = 0 then begin
  414.           write(outfile,j:2,' ');IOCHECK;   { write out sample number }
  415.         end;
  416.         write(outfile,i:3,data[i,j]:9:2);IOCHECK; { write out species couplet }
  417.         number_written := number_written + 1;
  418.         if number_written = 6 then begin          { 6 couplets per line }
  419.           writeln(outfile);IOCHECK;
  420.           number_written := 0;
  421.         end;
  422.       end;
  423.     end; { for i }
  424.     if number_written <> 0 then begin
  425.       writeln(outfile);IOCHECK;
  426.     end;
  427.   end;   { for j }
  428.   writeln(outfile,'00');     { end of data }
  429.   IOCHECK;
  430.  
  431. { write out labels }
  432.   if labels_present then begin
  433.     for i := 1 to rows do begin
  434.       write(outfile,row_lab[i]:8);IOCHECK;
  435.       if (i mod 10 = 0) or (i = rows) then begin  { 10 labels per line }
  436.         writeln(outfile);IOCHECK;
  437.       end;
  438.     end;
  439.     for i := 1 to columns do begin
  440.       write(outfile,col_lab[i]:8);IOCHECK;
  441.       if (i mod 10 = 0) or (i = columns) then begin  { 10 labels per line }
  442.         writeln(outfile);IOCHECK;
  443.       end;
  444.     end;
  445.   end
  446.   else begin        { leave blank lines if no labels }
  447.     writeln(outfile);IOCHECK;
  448.     for i := 1 to rows do
  449.       if i mod 10 = 0 then begin
  450.         writeln(outfile);IOCHECK;
  451.       end;
  452.     writeln(outfile);IOCHECK;
  453.     for i := 1 to columns do
  454.       if i mod 10 = 0 then begin
  455.         writeln(outfile);IOCHECK;
  456.       end;
  457.   end;
  458.   writeln(outfile,no_omitted_samples1);IOCHECK;
  459.   writeln(outfile,no_omitted_samples2);IOCHECK;
  460. END;
  461.  
  462. { ****************************************************************** }
  463.  
  464. PROCEDURE write_mvsp;
  465.  
  466. VAR
  467.   printwidth : integer;
  468.  
  469. BEGIN
  470.   writeln;write('Processing: ',infilename,' => ',outfilename,'...');
  471.  
  472. { write out header }
  473.   labels_present := false;
  474.   for i := 1 to 8 do
  475.     if col_lab[1][i] > space then labels_present := true;
  476.   if labels_present then begin
  477.     write(outfile,'*L ');IOCHECK;
  478.     printwidth := 7;
  479.   end
  480.   else begin
  481.     write(outfile,'* ');IOCHECK;
  482.     printwidth := 8;
  483.   end;
  484.   writeln(outfile,rows,' ',columns,' ',title);IOCHECK;
  485.  
  486. { write out column labels }
  487.   if labels_present then begin
  488.     for i := 1 to columns do begin
  489.       write(outfile,col_lab[i],' ');IOCHECK;
  490.       if i mod printwidth = 0 then begin
  491.         writeln(outfile);IOCHECK;
  492.       end;
  493.     end;
  494.     writeln(outfile);IOCHECK;
  495.   end;
  496.  
  497. { write out row labels & data }
  498.   for i := 1 to rows do begin
  499.     for j := 1 to columns do begin
  500.       if (labels_present) and (j = 1) then begin
  501.         write(outfile,row_lab[i],' ');IOCHECK;
  502.       end;
  503.       write(outfile,data[j,i]:8:2,' ');IOCHECK;
  504.       if j mod printwidth = 0 then begin
  505.         writeln(outfile);IOCHECK;
  506.       end;
  507.     end;
  508.     writeln(outfile);IOCHECK;
  509.   end;
  510. END;
  511.  
  512. { ****************************************************************** }
  513.  
  514. BEGIN                   { main handling routine }
  515. { initialize variables }
  516.   fillchar(data,sizeof(data),0);
  517.   fillchar(col_lab,sizeof(col_lab),' ');
  518.   fillchar(row_lab,sizeof(col_lab),' ');
  519.  
  520.   lowvideo;
  521.   writeln;
  522.   writeln('REFORMAT - Converts data files between MVSP and DECORANA formats');
  523.   writeln('    (C) Copyright - Warren L. Kovach - Feb., 1986');
  524.   writeln;
  525.   if (paramstr(1) = '') then begin
  526.     SYNTAX;        { give the user some help }
  527.     halt;
  528.   end;
  529.   OPENFILES;
  530.  
  531. { read file header }
  532.   read(infile,marker);IOCHECK;
  533.   reset(infile);IOCHECK;
  534.  
  535. { process file }
  536.   if marker = '*' then begin
  537.     writeln;writeln('Converting from MVSP to DECORANA format');
  538.     READ_MVSP;
  539.     WRITE_DECORANA;
  540.   end
  541.   else begin
  542.     writeln;writeln('Converting from DECORANA to MVSP format');
  543.     READ_DECORANA;
  544.     WRITE_MVSP;
  545.   end;
  546.  
  547.   close(infile);IOCHECK;
  548.   close(outfile);IOCHECK;
  549.   writeln('Done');
  550.   {$I+}
  551. END.